home *** CD-ROM | disk | FTP | other *** search
/ Aminet 21 / Aminet 21 (1997)(GTI - Schatztruhe)[!][Oct 1997].iso / Aminet / comm / bbs / cit_src_7H21.lha / netrcv.c < prev    next >
C/C++ Source or Header  |  1997-08-21  |  22KB  |  918 lines

  1. /*
  2. *       netrcv.c
  3. *
  4. *      Networking functions for reception.
  5. */
  6. /*
  7. *       history
  8. *
  9. * 86Aug20 HAW  History not maintained due to space problems.
  10. */
  11. #include "ctdl.h"
  12. /*
  13. *       Contents
  14. *
  15. * called()    Handle being called.
  16. * rcvStuff()    Manage receiving stuff.
  17. * netPwd()    Check password.
  18. * doResults()   Post-process results.
  19. * getId()     Get nodeId and nodeName from caller.
  20. * getNextCommand()  Get next command.
  21. * grabCommand()   Extract network cmds from buffer.
  22. * reply()     Sends a reply to caller.
  23. * reqReversal()   Handle role reversal.
  24. * reqCheckMail()    Check incoming mail.
  25. * targetCheck()   Check for existence of recipients.
  26. * CheckRecipient()  work fn for above.
  27. * doNetRooms()    Manage integrating incoming messages.
  28. * IntegrateRoom()   work fn for above.
  29. * ReadNetRoomFile() work fn for above.
  30. * getMail()   Handle incoming mail.
  31. * reqSendFile()   Receive a sent file.
  32. * netFileReq()    Senda a requested file.
  33. * netRRReq()    Handle room sharing.
  34. * recNetMessages()  Receive net messages.
  35. * UpdateRecoveryFile()  Updates the network recovery file.
  36. *   RoomRoutable()    Is this room routable?
  37. * IsRoomRoutable()  Is this room routable?
  38. * netMultiSend()    Send multiple files.
  39. * RecoverNetwork()  Recover from network disaster.
  40. */
  41. extern char logNetResults;
  42. char        netDebug = FALSE;
  43. char    processMail;
  44. char    PosId;
  45. char    *AssignAddress = NULL;
  46. #define RECOVERABLE 1
  47. extern char   *SR_Sent;
  48. extern FILE   *netLog, *netMisc;
  49. extern AN_UNSIGNED      RecBuf[];
  50. extern int    counter;
  51. extern int    callSlot;
  52. extern char   checkNegMail;
  53. extern char   inReceive;
  54. extern label    normed, callerName, callerId;
  55. extern char   RouteMailForHere;
  56. extern char   *LOC_NET, *NON_LOC_NET;
  57. char    normId(), getNetMessage();
  58. char    callOut();
  59. AN_UNSIGNED      inp();
  60. char *netRoomTemplate = "room%d.$$$";
  61. char *SharingRefusal[] =
  62.   {
  63.   "'%s' does not exist",
  64.   "'%s' is not a networking room",
  65.   "'%s' is not networking with you",
  66.   "No can do for '%s'",
  67.  
  68.   };
  69. extern char  RecMassTransfer;
  70. extern CONFIG    cfg;   /* Lots an lots of variables    */
  71. extern logBuffer logBuf;  /* Person buffer    */
  72. extern logBuffer logTmp;  /* Person buffer    */
  73. extern aRoom     roomBuf; /* Room buffer    */
  74. extern rTable    *roomTab;
  75. extern MessageBuffer   msgBuf;
  76. extern NetBuffer netBuf;
  77. extern NetTable  *netTab;
  78. extern int       thisNet;
  79. extern char      onConsole;
  80. extern char      loggedIn;  /* Is we logged in?   */
  81. extern char      outFlag; /* Output flag    */
  82. extern char      haveCarrier; /* Do we still got carrier?     */
  83. extern char      modStat; /* Needed so we don't die       */
  84. extern char      WCError;
  85. extern int       thisRoom;
  86. extern int       thisLog;
  87. extern char  *APPEND_TEXT, *WRITE_TEXT, *READ_TEXT;
  88. extern char  *R_SH_MARK, *NON_LOC_NET, *LOC_NET;
  89. extern long char_in, char_out, start_time;
  90.  
  91. /*
  92. * called()
  93. *
  94. * We've been called, so let's handle it.
  95. */
  96. void called()
  97.   {
  98.   ITL_InitCall();   /* Initialize the ITL layer */
  99.   memset(SR_Sent, 0, SHARED_ROOMS);
  100.   inReceive = TRUE;
  101.   RecMassTransfer = FALSE;
  102.   SpecialMessage("Status:Net Carrier");
  103.   if( logNetResults || netDebug )splitF(netLog, "Carrier %s\n", Current_Time());
  104.   processMail = checkNegMail = FALSE;
  105.   if (!called_stabilize())
  106.     {
  107.     if (cfg.BoolFlags.debug)splitF(netLog," Not Stabilized...\n");
  108.     return ;
  109.  
  110.     };
  111.   if( logNetResults && netDebug )splitF(netLog, "Stabilized\n");
  112.   SpecialMessage("Status:Net Session");
  113.   char_in = char_out = 0;
  114.   start_time = Set_Timer(0);       /* initialize time of day */
  115.   getId();
  116.   if (!haveCarrier) return;
  117.   rcvStuff(FALSE);
  118.   splitF(netLog, "Finished with %s @%s\n",  callerName, Current_Time());
  119.   Compute_Data(callerName);
  120.   pause(20);
  121.   killConnection();
  122.   doResults();
  123.   SpecialMessage("Status:Net Completed");
  124.  
  125.   }
  126. /*
  127. * rcvStuff()
  128. *
  129. * This function manages receiving stuff.
  130. */
  131. void rcvStuff(char reversed)
  132.   {
  133.   label     tempNm;
  134.   struct cmd_data cmds;
  135.   PosId = (callSlot == ERROR) ? FALSE : (netBuf.OurPwd[0] == 0 || (reversed && netBuf.nbflags.Stadel));
  136.   RouteMailForHere = FALSE;
  137.   do
  138.     {
  139.     getNextCommand(&cmds);
  140.     switch (cmds.command)
  141.       {
  142.       case HANGUP:          break;
  143.       case NORMAL_MAIL:    getMail();     break;
  144.       case A_FILE_REQ:
  145.       case R_FILE_REQ:     netFileReq(&cmds);   break;
  146.       case NET_ROOM:       netRRReq(&cmds, FALSE);  break;
  147.       case ROLE_REVERSAL:  reqReversal(reversed);   break;
  148.       case CHECK_MAIL:     reqCheckMail();    break;
  149.       case SEND_FILE:      reqSendFile(&cmds);    break;
  150.       case NET_ROUTE_ROOM: netRRReq(&cmds, TRUE);   break;
  151.       case SYS_NET_PWD:    netPwd(&cmds);     break;
  152.       case ITL_PROTOCOL:   ITL_rec_optimize(&cmds);       break;
  153.       case ITL_COMPACT:    ITL_RecCompact(&cmds);   break;
  154.       case ROUTE_MAIL:     netRouteMail(&cmds);   break;
  155.       case FAST_MSGS:  netFastTran(&cmds);    break;
  156.       default:
  157.       sprintf(tempNm, "'%d' unknown.", cmds.command);
  158.       reply(BAD, tempNm);   break;
  159.  
  160.       }
  161.  
  162.     }
  163.   while (gotCarrier() && cmds.command != HANGUP);
  164.  
  165.   }
  166. /*
  167. * netPwd()
  168. *
  169. * Check out the password sent to us, set flags appropriately.
  170. */
  171. void netPwd(struct cmd_data *cmds)
  172.   {
  173.   if (callSlot != ERROR)
  174.     {
  175.     PosId = !strCmpU(cmds->fields[0], netBuf.OurPwd);
  176.     if (!PosId)
  177.       {
  178.       if( logNetResults )splitF(netLog, "Bad pwd: -%s-\n", cmds->fields[0]);
  179.       sPrintf(msgBuf.mbtext, "%s sent bad password -%s-.",
  180.       callerName, cmds->fields[0]);
  181.       netResult(msgBuf.mbtext);
  182.  
  183.       }
  184.  
  185.     }
  186.   reply(GOOD, "");
  187.  
  188.   }
  189. /*
  190. * doResults()
  191. *
  192. * This function processes the results of receiving thingies and such.
  193. */
  194. void doResults()
  195.   {
  196.   extern SListBase DomainMap;
  197.   void HandleExistingDomain();
  198.   int i;
  199.   label temp;
  200.   extern int RMcount;
  201.   DisableModem(TRUE);
  202.   InitVortexing();    /* handles all mail for here */
  203.   if (processMail)
  204.     {
  205.     if (AddNetMsgs("tempmail.$$$", inMail, 2, MAILROOM, TRUE) == ERROR)
  206.     no_good("No mail file for %s?", TRUE);
  207.  
  208.     }
  209.   if (RouteMailForHere)
  210.     {
  211.     for (i = 0; ; i++)
  212.       {
  213.       sPrintf(temp, "rmail.%d", i);
  214.       if (AddNetMsgs(temp, inRouteMail, 2, MAILROOM, TRUE) == ERROR)
  215.       break;
  216.  
  217.       }
  218.     RMcount = 0;
  219.  
  220.     }
  221.   msgBuf.mbtext[0] = '\0';
  222.   FinVortexing();   /* finish handling mail */
  223.   if( msgBuf.mbtext[0] != '\0')
  224.     netResult(msgBuf.mbtext);  /* the vortex checker will setup this */
  225.  
  226.   if (callSlot == ERROR)
  227.     {
  228.     /* If didn't know this node, don't      */
  229.     EnableModem(TRUE);
  230.     return ;  /* bother with anything else  */
  231.  
  232.     }
  233.   if (checkNegMail) readNegMail(TRUE);
  234.   ReadFastFiles();    /* messages transferred in one big arc */
  235.   doNetRooms();
  236.   AdjustRoute();
  237.   netBuf.nbLastConnect = CurAbsolute();
  238.   putNet(thisNet, &netBuf);
  239.   UpdVirtStuff(); /* Just in case. */
  240.   RunList(&DomainMap, HandleExistingDomain);
  241.   RationalizeDomains(); /* again just in case ... */
  242.   EnableModem(TRUE);
  243.  
  244.   }
  245. /*
  246. * getId()
  247. *
  248. * This gets nodeId and nodeName from caller.
  249. */
  250. void getId()
  251.   {
  252.   char *secRunner;
  253.   #ifdef NEED_THIS_DATA
  254.   SYS_FILE fn;
  255.   #endif
  256.   int i;
  257.   extern long byteRate;
  258.   extern char *APPEND_ANY;
  259.   if (!haveCarrier) return;
  260.   ITL_Receive(NULL, FALSE, TRUE, putFLChar, fclose);
  261.   if (!gotCarrier())
  262.     {
  263.     return ;
  264.  
  265.     }
  266.   strncpy(callerId, RecBuf, NAMESIZE - 1);
  267.   secRunner = RecBuf;
  268.   while (*secRunner != 0) secRunner++;
  269.   secRunner++;
  270.   strncpy(callerName, secRunner, NAMESIZE - 1);
  271.   normId(callerId, normed);
  272.   if (strLen(callerName) == 0 || strLen(callerId) == 0)
  273.     {
  274.     if( logNetResults )splitF(netLog, "getId invalid data, dropping connection.\n\n");
  275.     killConnection();
  276.     #ifdef NEED_THIS_DATA
  277.     makeSysName(fn, "getid.sys", &cfg.netArea);
  278.     if ((upfd = safeopen(fn, APPEND_ANY)) != NULL)
  279.       {
  280.       fwrite(RecBuf, SECTSIZE, 1, upfd);
  281.       fclose(upfd);
  282.  
  283.       }
  284.     #endif
  285.  
  286.     }
  287.   if ((callSlot = searchNet(normed, &netBuf)) == ERROR)
  288.     {
  289.     sPrintf(msgBuf.mbtext, "New caller: %s (%s)", callerName, callerId);
  290.     netResult(msgBuf.mbtext);
  291.  
  292.     }
  293.   else
  294.     {
  295.     for (i = 0; i < SHARED_ROOMS; i++)
  296.     resetNeedsProcessing(i);
  297.     putNet(callSlot, &netBuf);
  298.  
  299.     }
  300.   if( logNetResults)splitF(netLog, "%s (%s) @ %ld\n", callerName, callerId, byteRate * 10L);
  301.  
  302.   }
  303. /*
  304. * getNextCommand()
  305. *
  306. * This gets next command (facility request) from the caller.
  307. */
  308. void getNextCommand(struct cmd_data *cmds)
  309.   {
  310.   zero_struct(*cmds);
  311.   ITL_Receive(NULL, FALSE, TRUE, putFLChar, fclose);
  312.   if (!gotCarrier())
  313.     {
  314.     return ;
  315.  
  316.     }
  317.   grabCommand(cmds, RecBuf);
  318.   }
  319. /*
  320. * grabCommand()
  321. *
  322. * This pulls network cmds out of the specified buffer.
  323. */
  324. void grabCommand(struct cmd_data *cmds, char *sect)
  325.   {
  326.   int fcount = 0;
  327.   cmds->command = sect[0];
  328.   sect++;
  329.   while (sect[0] > 0 && fcount < 4)
  330.     {
  331.     strncpy(cmds->fields[fcount], sect, NAMESIZE - 1);
  332.     cmds->fields[fcount][NAMESIZE - 1] = 0;
  333.     fcount++;
  334.     while (*sect != 0) sect++;
  335.     sect++;
  336.  
  337.     }
  338.   }
  339. /*
  340. * reply()
  341. *
  342. * This sends a full reply to the caller's request.
  343. */
  344. void reply(char state, char *reason)
  345.   {
  346.   if (!ITL_Send(STARTUP))
  347.     {
  348.     no_good("Couldn't send reply to %s!", TRUE);
  349.     return;
  350.  
  351.     }
  352.   sendITLchar(state);
  353.   if (state == BAD)
  354.     {
  355.     mTrPrintf("%s", reason);
  356.     if (cfg.BoolFlags.debug) splitF(netLog, "Replying BAD: %s\n", reason);
  357.  
  358.     }
  359.   sendITLchar(0);
  360.   ITL_Send(FINISH);
  361.  
  362.   }
  363. /*
  364. * reqReversal()
  365. *
  366. * This handles the role reversal command.
  367. */
  368. void reqReversal(char reversed)
  369.   {
  370.   if ( logNetResults && netDebug ) splitF(netLog, "Role reversal\n");
  371.   if (reversed)
  372.     {
  373.     reply(BAD, "Synch error on Reversal!");
  374.     return ;
  375.  
  376.     }
  377.   reply(GOOD, "");
  378.   if (callSlot == ERROR)      /* Forces a "null" role reversal  */
  379.   zero_struct(netBuf.nbflags);
  380.   sendStuff(TRUE, PosId);
  381.  
  382.   }
  383. /*
  384. * reqCheckMail()
  385. *
  386. * This checks incoming mail and does negative acks where appropriate.
  387. */
  388. void reqCheckMail()
  389.   {
  390.   if( logNetResults && netDebug )splitF(netLog, "checking Mail\n");
  391.   if (!processMail)
  392.     {
  393.     reply(BAD, "No mail to check!");
  394.     return ;
  395.  
  396.     }
  397.   reply(GOOD, "");
  398.   if (ITL_Send(STARTUP))
  399.     {
  400.     AddNetMsgs("tempmail.$$$", targetCheck, FALSE, MAILROOM, TRUE);
  401.     sendITLchar(NO_ERROR);
  402.     ITL_Send(FINISH);
  403.  
  404.     }
  405.  
  406.   }
  407. /*
  408. * targetCheck()
  409. *
  410. * This checks for existence of recipients.
  411. */
  412. void targetCheck()
  413.   {
  414.   if (HasOverrides(&msgBuf))
  415.     {
  416.     RunList(&msgBuf.mbOverride, CheckRecipient);
  417.  
  418.     }
  419.   else
  420.     {
  421.     CheckRecipient(msgBuf.mbto);
  422.  
  423.     }
  424.  
  425.   }
  426. /*
  427. * CheckRecipient()
  428. *
  429. * This will check to see if the recipient exists.
  430. */
  431. void CheckRecipient(char *d)
  432.   {
  433.   char     sigChar;
  434.   if (!d[0])
  435.     {
  436.     sigChar = BAD_FORM;
  437.  
  438.     }
  439.   else if (strchr(d, '!') != NULL)
  440.   return ;  /* STadel routed mail - don't try to check it here */
  441.   else
  442.     {
  443.     if (PersonExists(d) != ERROR)
  444.     return ;
  445.     else
  446.     sigChar = NO_RECIPIENT;
  447.  
  448.     }
  449.   sendITLchar(sigChar);
  450.   mTrPrintf("%s", msgBuf.mbauth);
  451.   mTrPrintf("%s", d);
  452.   mTrPrintf("%s @ %s", msgBuf.mbdate, msgBuf.mbtime);
  453.  
  454.   }
  455. /*
  456. * doNetRooms()
  457. *
  458. * This function integrates temporary files containing incoming messages into
  459. * the data base.
  460. */
  461. void doNetRooms()
  462.   {
  463.   SYS_FILE fileNm;
  464.   int IntegrateRoom(SharedRoom *room, int system, int index, int roomslot,
  465.   void *d);
  466.   EachSharedRoom(thisNet, IntegrateRoom, NULL, NULL);
  467.   makeSysName(fileNm, RECOVERY_FILE, &cfg.netArea);
  468.   unlink(fileNm);
  469.  
  470.   }
  471. /*
  472. * IntegrateRoom()
  473. *
  474. * This function helps integrate incoming messages into a room.
  475. */
  476. int IntegrateRoom(SharedRoom *room, int system, int index, int roomslot,
  477. void *d)
  478.   {
  479.   if (chkNeedsProcessing(index))
  480.     {
  481.     ReadNetRoomFile(index, NULL);
  482.     resetNeedsProcessing(index);
  483.  
  484.     }
  485.   if (SR_Sent[index] == 1)
  486.   netBuf.netRooms[index].lastMess =  roomTab[roomslot].rtlastMessage;
  487.   return TRUE;
  488.  
  489.   }
  490. /*
  491. * ReadNetRoomFile()
  492. *
  493. * This function reads in a file of messages received on net.
  494. * NB: the passed parameter is the index into the netBuf.netRooms
  495. * pseudo-array, not the number of the room itself.  See the code.
  496. */
  497. void ReadNetRoomFile(int rover, char *fn)
  498.   {
  499.   label temp2;
  500.   if (cfg.BoolFlags.debug)splitF(netLog," ReadNetRoomFile(Rover:%d, fn:%s)\n",rover,(fn== NULL) ? "NULL":fn);
  501.   if (fn == NULL) sPrintf(temp2, netRoomTemplate, netRoomSlot(rover));
  502.   getRoom(netRoomSlot(rover));
  503.   if (roomBuf.rbShareType != PEON &&
  504.   CGetMode(netBuf.netRooms[rover].mode) != PEON)
  505.   AssignAddress = NON_LOC_NET;
  506.   else
  507.   AssignAddress = LOC_NET;
  508.   InitVortexing();
  509.   AddNetMsgs((fn == NULL) ? temp2 : fn, inMail, TRUE, netRoomSlot(rover),
  510.   (fn == NULL));
  511.  
  512.   msgBuf.mbtext[0] = '\0';
  513.   FinVortexing();   /* finish handling Room */
  514.   if( msgBuf.mbtext[0] != '\0')
  515.     netResult(msgBuf.mbtext);  /* the vortex checker will setup this */
  516.  
  517.   AssignAddress = NULL;
  518.  
  519.   }
  520. /*
  521. * getMail()
  522. *
  523. * This function Grabs mail from caller.
  524. */
  525. void getMail()
  526.   {
  527.   SYS_FILE tempNm;
  528.   if( netDebug && logNetResults) splitF(netLog, "Receiving Mail\n");
  529.   makeSysName(tempNm, "tempmail.$$$", &cfg.netArea);
  530.   if (ITL_StartRecMsgs(tempNm, TRUE, TRUE, NULL) == ITL_SUCCESS)
  531.     {
  532.     processMail = TRUE;
  533.  
  534.     }
  535.  
  536.   }
  537. /*
  538. * reqSendFile()
  539. *
  540. * This function handles receiving a sent file.  Note that it handles file
  541. * redirection.
  542. */
  543. void reqSendFile(struct cmd_data *cmds)
  544.   {
  545.   long  proposed;
  546.   int count;
  547.   char work[100], work1[100], *Dir;
  548.   extern char *READ_ANY, *WRITE_ANY;
  549.   static char *Reject = "File %s from %s rejected because %s.";
  550.   /* don't accept files from rogues */
  551.   if (!PosId)
  552.     {
  553.     reply(BAD, "No room for file.");
  554.     return;
  555.  
  556.     }
  557.   /* handle incoming file redirection */
  558.   if ((Dir = RedirectFile(cmds->fields[0], netBuf.netName)) != NULL ||
  559.   (Dir = RedirectFile(cmds->fields[0], netBuf.nbShort)) != NULL)
  560.     {
  561.     RedirectName(work1, Dir, "mm12"); /* temp file name */
  562.     unlink(work1);  /* kill any prior backups (shouldn't be any ...) */
  563.     RedirectName(work, Dir, cmds->fields[0]);
  564.     if (access(work, 0) == 0)
  565.     rename(work, work1);
  566.  
  567.     }
  568.   else if (netSetNewArea(&cfg.receptArea))
  569.     {
  570.     proposed = atol(cmds->fields[2]);
  571.     if (sysRoomLeft() < proposed ||
  572.     proposed > ((long) cfg.maxFileSize) * 1024l)
  573.       {
  574.       reply(BAD, "No room for file.");
  575.       sPrintf(msgBuf.mbtext, Reject, cmds->fields[0], callerName,
  576.       proposed > ((long) cfg.maxFileSize) * 1024l ?
  577.       "the file was larger than #MAX_NET_FILE" :
  578.       "there was not enough room left in reception directory");
  579.       netResult(msgBuf.mbtext);
  580.       homeSpace();
  581.       return;
  582.  
  583.       }
  584.     count = 0;
  585.     strCpy(work, cmds->fields[0]);
  586.     while (access(work, 0) != -1)
  587.       {
  588.       sPrintf(work, "a.%d", count++);
  589.  
  590.       }
  591.  
  592.     }
  593.   else
  594.     {
  595.     reply(BAD, "System error");
  596.     return ;
  597.  
  598.     }
  599.   reply(GOOD, NULL);
  600.   if( logNetResults )splitF(netLog, "File Reception: %s\n", cmds->fields[0]);
  601.   ITL_Receive(work, FALSE, TRUE, putFLChar, fclose);
  602.   homeSpace();
  603.   if (haveCarrier)
  604.     {
  605.     if (strCmp(work, cmds->fields[0]) == SAMESTRING || Dir != NULL)
  606.     sPrintf(msgBuf.mbtext, "%s received from %s.", cmds->fields[0],
  607.     callerName);
  608.     else
  609.     sPrintf(msgBuf.mbtext, "%s (saved as %s) received from %s.",
  610.     cmds->fields[0], work, callerName);
  611.     netResult(msgBuf.mbtext);
  612.     if (Dir != NULL)  /* kill temporary bkp of redirected file */
  613.     unlink(work1);
  614.  
  615.     }
  616.   else if (Dir != NULL) /* failed transfer of redirected file */
  617.   rename(work1, work);
  618.  
  619.   }
  620. /*
  621. * netFileReq()
  622. *
  623. * This will handle requests for file transfers.
  624. */
  625. void netFileReq(struct cmd_data *cmds)
  626.   {
  627.   int  roomSlot;
  628.   extern char *READ_ANY;
  629.   if( logNetResults)splitF(netLog, "File request: %s in %s\n", cmds->fields[1],
  630.   cmds->fields[0]);
  631.   /* allow disabling this feature on a system by system basis */
  632.   if (PosId && netBuf.nbflags.NoDL)
  633.     {
  634.     reply(BAD, "Downloading disabled.");
  635.     return;
  636.  
  637.     }
  638.   if ((roomSlot = roomExists(cmds->fields[0])) == ERROR   ||
  639.   !roomTab[roomSlot].rtflags.ISDIR  ||
  640.   roomTab[roomSlot].rtflags.NO_NET_DOWNLOAD ||
  641.   !roomTab[roomSlot].rtflags.DOWNLOAD)
  642.     {
  643.     sPrintf(msgBuf.mbtext, "Room %s does not exist.", cmds->fields[0]);
  644.     reply(BAD, msgBuf.mbtext);
  645.     return;
  646.  
  647.     }
  648.   getRoom(roomSlot);
  649.   if (!setSpace(&roomBuf))
  650.     {
  651.     reply(BAD, "Directory error");
  652.     return;
  653.  
  654.     }
  655.   if (cmds->command == A_FILE_REQ)
  656.     {
  657.     reply(GOOD, "");
  658.     sPrintf(msgBuf.mbtext, "Following files sent to %s from %s: ",
  659.     callerName, roomBuf.rbname);
  660.     wildCard(netMultiSend, cmds->fields[1], FALSE, "", FALSE);
  661.     if (ITL_Send(STARTUP))
  662.       {
  663.       mTrPrintf("");
  664.       ITL_Send(FINISH);
  665.  
  666.       }
  667.  
  668.     }
  669.   else
  670.     {
  671.     if (access(cmds->fields[1], 4) == -1)
  672.       {
  673.       sPrintf(msgBuf.mbtext, "There is no '%s' in %s.", cmds->fields[1],
  674.       cmds->fields[0]);
  675.       reply(BAD, msgBuf.mbtext);
  676.       homeSpace();
  677.       return;
  678.  
  679.       }
  680.     reply(GOOD, "");
  681.     SendHostFile(cmds->fields[1]);
  682.     sPrintf(msgBuf.mbtext,
  683.     "%s downloaded from %s by %s.",
  684.     cmds->fields[1], formRoom(thisRoom, FALSE, FALSE), callerName);
  685.  
  686.     }
  687.   homeSpace();
  688.   netResult(msgBuf.mbtext);
  689.  
  690.   }
  691. /*
  692. * netRRReq()
  693. *
  694. * This function handles room sharing.  If SendBack is TRUE then this is a
  695. * room routing (LD) request and requires we send the room's current contents
  696. * back.
  697. */
  698. void netRRReq(struct cmd_data *cmds, char SendBack)
  699.   {
  700.   RoomSearch arg;
  701.   char reason[50];
  702.   strCpy(arg.Room, cmds->fields[0]);
  703.   if (!RoomRoutable(&arg))
  704.     {
  705.     sPrintf(reason, SharingRefusal[arg.reason], cmds->fields[0]);
  706.     if( logNetResults )splitF(netLog, "Refusing to share %s (%s)\n", cmds->fields[0], reason);
  707.     reply(BAD, reason);
  708.     return;
  709.  
  710.     }
  711.   if (!arg.virtual)
  712.     {
  713.     getRoom(arg.room);
  714.     recNetMessages(arg.index, arg.Room, arg.room, TRUE);
  715.     if (SendBack)
  716.     findAndSend(ERROR, R_SH_MARK, LOC_NET,
  717.     roomBuf.rbShareType == BACKBONE ? NON_LOC_NET : NULL, arg.index,
  718.     RoomSend, roomBuf.rbname, RoomReceive);
  719.  
  720.     }
  721.   else
  722.     {
  723.     RecVirtualRoom(arg.index, TRUE);
  724.     if (SendBack)
  725.     findAndSend(ERROR, NULL, NULL, NULL, arg.index, SendVirtual,
  726.     arg.Room, RecVirtualRoom);
  727.  
  728.     }
  729.  
  730.   }
  731. /*
  732. * recNetMessages()
  733. *
  734. * This function receives net messages.  This is not the same as processing
  735. * them.
  736. */
  737. void recNetMessages(int arraySlot, char *name, int slot, char ReplyFirst)
  738.   {
  739.   SYS_FILE fileNm, temp;
  740.   char reason[60];
  741.   if( logNetResults && netDebug )splitF(netLog, "Receiving %s\n", name);
  742.   sPrintf(temp, netRoomTemplate, slot);
  743.   makeSysName(fileNm, temp, &cfg.netArea);
  744.   switch (ITL_StartRecMsgs(fileNm, ReplyFirst, TRUE, NULL))
  745.     {
  746.     case ITL_SUCCESS:
  747.     setNeedsProcessing(arraySlot);
  748.     UpdateRecoveryFile(name);
  749.     break;
  750.     case ITL_NO_OPEN:
  751.     sPrintf(reason, "Internal error for %s", name);
  752.     reply(BAD, reason);
  753.     break;
  754.     case ITL_BAD_TRANS:
  755.     break;
  756.  
  757.     }
  758.  
  759.   }
  760. /*
  761. * UpdateRecoveryFile()
  762. *
  763. * This function updates the network recovery file.
  764. */
  765. void UpdateRecoveryFile(char *val)
  766.   {
  767.   SYS_FILE fileNm;
  768.   makeSysName(fileNm, RECOVERY_FILE, &cfg.netArea);
  769.   if (access(fileNm, 0) != 0)
  770.   CallMsg(fileNm, callerId);
  771.   CallMsg(fileNm, val);
  772.  
  773.   }
  774. /*
  775. * RoomRoutable()
  776. *
  777. * Is this room routable?
  778. */
  779. char RoomRoutable(RoomSearch *data)
  780.   {
  781.   if( netDebug && cfg.BoolFlags.debug )
  782.     {
  783.     splitF(netLog, "label Room(%s)  ", data->Room);     /* this is the target */
  784.     splitF(netLog, "char  virtual(%x)",data->virtual);  /* is virtual? */
  785.     splitF(netLog, "int   room(%d)",   data->room);     /* room slot */
  786.     splitF(netLog, "int   index(%d)",  data->index);
  787.     splitF(netLog, "char  reason(%x)", data->reason);
  788.     };
  789.   if (!PosId)
  790.     {
  791.     if( logNetResults && netDebug )splitF(netLog, "-No Password.-");
  792.     data->reason = NO_PWD;
  793.     return FALSE;
  794.  
  795.     }
  796.   if (callSlot == ERROR)
  797.     {
  798.     if( logNetResults && netDebug )splitF(netLog, "-Not sharing.-");
  799.     data->reason = NOT_SHARING;
  800.     return FALSE;
  801.  
  802.     }
  803.   data->reason = NO_ROOM;
  804.   data->virtual = FALSE;
  805.   EachSharedRoom(thisNet, IsRoomRoutable, VirtRoomRoutable, data);
  806.   return (char)(data->reason == FOUND);
  807.  
  808.   }
  809. /*
  810. * IsRoomRoutable()
  811. *
  812. * This function checks to see if the given shared room matches with the
  813. * argument presented in the void pointer parameter.
  814. */
  815. int IsRoomRoutable(SharedRoom *room, int system, int index, int roomslot,
  816. void *d)
  817.   {
  818.   RoomSearch *arg;
  819.   arg = d;
  820.   if (strCmpU(roomTab[roomslot].rtname, arg->Room) == SAMESTRING)
  821.     {
  822.     if (roomTab[roomslot].rtflags.SHARED == 0)
  823.     arg->reason = NOT_SHARING;
  824.     else
  825.     arg->reason = FOUND;
  826.     arg->room = roomslot;
  827.     arg->index = index;
  828.     return ERROR;   /* stop searching */
  829.  
  830.     }
  831.   return TRUE;
  832.  
  833.   }
  834. /*
  835. * netMultiSend()
  836. *
  837. * This function will send requested files via the net.
  838. */
  839. void netMultiSend(DirEntry *fn)
  840.   {
  841.   long Sectors;
  842.   if (!gotCarrier()) return ;
  843.   strCat(msgBuf.mbtext, fn->unambig);
  844.   strCat(msgBuf.mbtext, " ");
  845.   Sectors     = ((fn->FileSize + 127) / SECTSIZE);
  846.   if (ITL_Send(STARTUP))
  847.     {
  848.     mTrPrintf("%s", fn->unambig);
  849.     mTrPrintf("%ld", Sectors);
  850.     ITL_Send(FINISH);
  851.  
  852.     }
  853.   SendHostFile(fn->unambig);
  854.  
  855.   }
  856. /*
  857. * RecoverNetwork()
  858. *
  859. * This function is called during system startup.  If a disaster hit during
  860. * a network session, this will try to recover messages already transferred
  861. * from files left in the network directory.
  862. */
  863. void RecoverNetwork()
  864.   {
  865.   SYS_FILE fileNm;
  866.   char line[50];
  867.   label temp;
  868.   int rover;
  869.   FILE *fd;
  870.   RoomSearch arg;
  871.   extern char inNet;
  872.   makeSysName(fileNm, RECOVERY_FILE, &cfg.netArea);
  873.   if ((fd = safeopen(fileNm, READ_TEXT)) == NULL)
  874.   return;   /* normal */
  875.   inNet = NORMAL_NET;
  876.   SpecialMessage("Network Cleanup");
  877.   if (GetAString(line, sizeof line, fd) != NULL)
  878.     {
  879.     if (searchNet(line, &netBuf) != ERROR)
  880.       {
  881.       PosId = TRUE;
  882.       while (GetAString(line, sizeof line, fd) != NULL)
  883.         {
  884.         if (strncmp(line, FAST_TRANS_FILE, strLen(FAST_TRANS_FILE))
  885.         == SAMESTRING)
  886.         RecoverMassTransfer(line);
  887.         else
  888.           {
  889.           strCpy(arg.Room, line);
  890.           if (RoomRoutable(&arg) && !arg.virtual)
  891.             {
  892.             printf("%s\n", line);
  893.             ReadNetRoomFile(arg.index, NULL);
  894.  
  895.             }
  896.  
  897.           }
  898.  
  899.         }
  900.       readNegMail(FALSE);
  901.       AddNetMsgs("tempmail.$$$", inMail, 2, MAILROOM, TRUE);
  902.       for (rover = 0; ; rover++)
  903.         {
  904.         sPrintf(temp, "rmail.%d", rover);
  905.         if (AddNetMsgs(temp, inRouteMail, 2, MAILROOM, TRUE) == ERROR)
  906.         break;
  907.  
  908.         }
  909.  
  910.       }
  911.  
  912.     }
  913.   fclose(fd);
  914.   unlink(fileNm);
  915.   inNet = NON_NET;
  916.  
  917.   }
  918.